<?php

namespace Platform\Models\Admin;

use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Platform\Models\Traits\PermissionTrait;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Foundation\Auth\User;
use Illuminate\Support\Facades\Storage;

class Administrator extends User implements JWTSubject
{
    use PermissionTrait,SoftDeletes;

    protected $table = 'admins';

    public static $STATE_LOCK = 0;
    public static $STATE_NORMAL = 1;

    protected $fillable = ['username', 'password', 'name', 'avatar','phone','department_id'];
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function permission_model()
    {
        return Permission::class;
    }

    /**
     * 获取avatar_url时拼接url
     * @return string
     */
    public function getAvatarUrlAttribute(){
        if ($this->avatar) {
            return Storage::disk('public')->url($this->avatar);
        }
        return env('APP_URL').config('admin.default_avatar');
    }

    /**
     * 获取当前登陆的管理员
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public static function user()
    {
        return auth('admin')->user();
    }

    /**
     * 绑定与角色之间的关系
     * @return BelongsToMany
     * fixme 改为一对多的关系
     *
    public function roles() : BelongsToMany
    {
        return $this->belongsToMany(LeaderRole::class, 'admin_role_users', 'user_id', 'role_id');
    }
    */

    /**
     * 绑定与角色之间的关系
     * @return BelongsTo
     */
    public function department() : BelongsTo
    {
        return $this->belongsTo(Department::class, 'department_id', 'id');
    }

    /**
     * 是否是超级管理员
     *
     * @return bool
     */
    public function isAdmin()
    {
        $adminstrators = config('admin.administrators');
        return in_array($this->id, $adminstrators) || (isset($this->department) ? $this->isDepartmentAdmin($this->department) : false);
    }

    /**
     * 根据标识过滤用户部门(用户角色)
     * Check if user is $department.
     * @param Department $department
     * @return mixed
     */
    public function isDepartmentAdmin(Department $department = null) : bool
    {
        /* fixme 角色关系变为一对多
        return $this->roles->pluck('slug')->contains($role);
        */
        if ($department)
            return $department->isAdmin();
        else return false;
    }

    /**
     * 获取当前管理员所能访问的菜单
     * @return array
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function menu()
    {
        $tree = (new Menu())->toTree();
        if ($this->isAdmin()) {
            return $tree;
        }

        $permissions = array_get($this->allPermissions(), 'GET');
        return $this->permissionsToMenu($permissions, $tree);
    }

    /**
     * 根据权限（接口地址+方法）过滤菜单
     * @param array $permissions
     * @param array $menuTree
     * @return array
     */
    protected function permissionsToMenu(array $permissions, array &$menuTree)
    {
        foreach ($menuTree as $key => &$menu) {
            if (isset($menu['children']) && !empty($menu['children'])) {
                $menu['children'] = $this->permissionsToMenu($permissions, $menu['children']);
            }

            /* TODO 需要跟前端商量，无子菜单则删除
            if (!in_array($menu['permission_uri'], $permissions) && empty($menu['children'])) {
                unset($menuTree[$key]);
            }
            */
            if ($menu['permission_uri'] && !in_array($menu['permission_uri'], $permissions)) {
                unset($menuTree[$key]);
            }
        }

        return array_values($menuTree);
    }

    /**
     * 使用 JWT auth 需要继承的方法
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * 使用 JWT auth 需要继承的方法
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}
